/**    
 * 文件名：DDLFormatterImpl.java</br>
 *    
 * 版本信息：v1.0</br>
 * 日期：2017年7月11日</br>
 * © 2005-2017 雷技信息科技（上海）有限公司版权所有</br>
 *
 */
package com.logic.common.sqlformat;

import java.util.StringTokenizer;

/**
 *
 * 项目名称：system-server</br>
 * 类名称：DDLFormatterImpl</br>
 * 类描述：</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年7月11日 下午6:15:39</br>
 * @version 1.0
 *
 */
public class DDLFormatterImpl implements Formatter
{
    public String format(String sql)
    {
        if (sql.toLowerCase().startsWith("create table"))
        {
            return formatCreateTable(sql);
        }
        if (sql.toLowerCase().startsWith("alter table"))
        {
            return formatAlterTable(sql);
        }
        if (sql.toLowerCase().startsWith("comment on"))
        {
            return formatCommentOn(sql);
        }
        
        return "\n    " + sql;
    }
    
    private String formatCommentOn(String sql)
    {
        StringBuffer result = new StringBuffer(60).append("\n    ");
        StringTokenizer tokens = new StringTokenizer(sql, " '[]\"", true);
        
        boolean quoted = false;
        while (tokens.hasMoreTokens())
        {
            String token = tokens.nextToken();
            result.append(token);
            if (isQuote(token))
            {
                quoted = !quoted;
            }
            else if ((!quoted) && ("is".equals(token)))
            {
                result.append("\n       ");
            }
            
        }
        
        return result.toString();
    }

    private String formatAlterTable(String sql)
    {
        StringBuffer result = new StringBuffer(60).append("\n    ");
        StringTokenizer tokens = new StringTokenizer(sql, " (,)'[]\"", true);
        
        boolean quoted = false;
        while (tokens.hasMoreTokens())
        {
            String token = tokens.nextToken();
            if (isQuote(token))
            {
                quoted = !quoted;
            }
            else if ((!quoted) && (isBreak(token)))
            {
                result.append("\n        ");
            }
            
            result.append(token);
        }
        
        return result.toString();
    }

    private String formatCreateTable(String sql)
    {
        StringBuffer result = new StringBuffer(60).append("\n    ");
        StringTokenizer tokens = new StringTokenizer(sql, "(,)'[]\"", true);
        
        int depth = 0;
        boolean quoted = false;
        while (tokens.hasMoreTokens())
        {
            String token = tokens.nextToken();
            if (isQuote(token))
            {
                quoted = !quoted;
                result.append(token);
            }
            else if (quoted)
            {
                result.append(token);
            }
            else
            {
                if (")".equals(token))
                {
                    depth--;
                    if (depth == 0)
                    {
                        result.append("\n    ");
                    }
                }
                result.append(token);
                if ((",".equals(token)) && (depth == 1))
                {
                    result.append("\n       ");
                }
                if ("(".equals(token))
                {
                    depth++;
                    if (depth == 1)
                    {
                        result.append("\n        ");
                    }
                }
            }
        }
        
        return result.toString();
    }

    private static boolean isBreak(String token)
    {
      return ("drop".equals(token)) || 
        ("add".equals(token)) || 
        ("references".equals(token)) || 
        ("foreign".equals(token)) || 
        ("on".equals(token));
    }

    private static boolean isQuote(String tok)
    {
      return ("\"".equals(tok)) || 
        ("`".equals(tok)) || 
        ("]".equals(tok)) || 
        ("[".equals(tok)) || 
        ("'".equals(tok));
    }
}
